﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Apollo.Web;
using System.IO;
using System.Configuration;
using NHibernate;
using LumenWorks.Framework.IO.Csv;

namespace Apollo.Website
{
    public partial class BulkImportStep1 : System.Web.UI.Page, IApolloPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Directory.Exists(MapPath(ConfigurationManager.AppSettings["BulkImportFilePath"])))
                MessageList.AddMessage(new ActionMessage("No folder found!", ActionMessageType.Error));

            if (!this.Page.IsPostBack)
                PopulateEntities();
        }

        protected void PopulateEntities() {
            DropDownListEntities.DataTextField = "Name";
            DropDownListEntities.DataValueField = "Id";

            DropDownListEntities.DataSource = Apollo.Application.CurrentSession.QueryOver<Entity>()
                .OrderBy(e => e.Name).Asc
                .List();
            DropDownListEntities.DataBind();
        }

        protected void ButtonSave_Click(object sender, EventArgs e) {
            if (!FileUploadImport.HasFile) {
                MessageList.AddMessage(new ActionMessage("No file attached!", ActionMessageType.Error));
                return;
            }

            try
            {
                string fileName = DateTime.Now.Ticks.ToString() + ".csv";

                FileUploadImport.SaveAs(MapPath(ConfigurationManager.AppSettings["BulkImportFilePath"]
                    + "/"
                    + fileName));

                BulkImport import = new BulkImport() {
                    Entity = Apollo.Application.CurrentSession.QueryOver<Entity>()
                                .Where(en => en.Id == int.Parse(DropDownListEntities.SelectedValue))
                                .SingleOrDefault(),
                    FilePath = ConfigurationManager.AppSettings["BulkImportFilePath"] + "/" + fileName,
                    ImportBy = this.User.Identity.Name,
                    ImportDate = DateTime.Now,
                    Name = FileUploadImport.FileName
                };

                ITransaction tran = Apollo.Application.CurrentSession.BeginTransaction();

                try
                {
                    Apollo.Application.CurrentSession.Save(import);

                    tran.Commit();

                    this.GenerateImportProjections(import);

                    Response.Redirect("BulkImportStep2.aspx?Id=" + import.Id.ToString());
                }
                catch {
                    tran.Rollback();
                }
            }
            catch (Exception ex) {
                MessageList.AddMessage(new ActionMessage(ex.Message, ActionMessageType.Error));
            }
        }


        protected void GenerateImportProjections(BulkImport import) {
            using (CsvReader csvReader = new CsvReader(new StreamReader(MapPath(import.FilePath)), true)) { 
                foreach(string header in csvReader.GetFieldHeaders()){
                    ITransaction tran = Apollo.Application.CurrentSession.BeginTransaction();

                    try
                    {
                        BulkImportProjection projection = new BulkImportProjection(){
                            BulkImport = import,
                            ColumnNumber = csvReader.GetFieldIndex(header),
                            Name = header
                        };
                        
                        Apollo.Application.CurrentSession.Save(projection);

                        tran.Commit();
                    }
                    catch(Exception ex) {
                        tran.Rollback();

                        MessageList.AddMessage(new ActionMessage("Failed to generate column for \""+header+"\": " + ex.Message, ActionMessageType.Error));
                    }
                }
            }
        }


        public int SelectedMenuItemID
        {
            get { return Apollo.Application.Meta<Apollo.MenuItem>().Single<Apollo.MenuItem>(mi => mi.Name == "Bulk import").Id; }
        }

        public int SelectedRootMenuItemId
        {
            get { return Apollo.Application.Meta<Apollo.MenuItem>().Single<Apollo.MenuItem>(mi => mi.Name == "Settings").Id; }
        }
    }
}